package com.financial.transactionhistory.service.impl;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

import ch.qos.logback.core.joran.util.beans.BeanUtil;
import com.alibaba.fastjson2.JSON;
import com.financial.common.constant.CacheConstants;
import com.financial.common.utils.DateUtils;
import com.financial.common.utils.SecurityUtils;
import com.financial.transactionhistory.dto.FinancialTransactionAddDto;
import com.financial.transactionhistory.dto.FinancialTransactionListDto;
import com.financial.transactionhistory.vo.FinancialTransactionVo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import com.financial.transactionhistory.mapper.FinancialTransactionMapper;
import com.financial.transactionhistory.domain.FinancialTransaction;
import com.financial.transactionhistory.service.IFinancialTransactionService;

import com.financial.transactionhistory.mapper.FinancialTransactionMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.util.CollectionUtils;

import java.util.Arrays;
import java.util.stream.Collectors;

/**
 * 交易记录Service业务层处理
 *
 * @author chenda
 * @date 2025-06-15
 */
@Service
@Slf4j
public class FinancialTransactionServiceImpl extends ServiceImpl<FinancialTransactionMapper, FinancialTransaction> implements IFinancialTransactionService {
    @Autowired
    private FinancialTransactionMapper financialTransactionMapper;

    /**
     * 查询交易记录
     *
     * @param id 交易记录主键
     * @return 交易记录
     */
    @Override
    public FinancialTransactionVo selectFinancialTransactionById(Long id) {

        //先查询redis中的数据
        String userIdStr = SecurityUtils.getUserId().toString();//当前用户id
        String cacheKey = CacheConstants.FINANCIAL_TRANSACTION_LIST_KEY + userIdStr;
        List<String> financialredisList = redisTemplate.opsForList().range(cacheKey, 0, -1);
        if (financialredisList.size()>0){
            FinancialTransactionVo financialTransactionVo = new FinancialTransactionVo();
            //遍历从redis中查询到的商品
            financialredisList.forEach(x->{
                //把查询到的商品转化成对象
                FinancialTransaction financialTransaction = JSON.parseObject(x, FinancialTransaction.class);
                Long financialTransactionId = financialTransaction.getId();
                if (financialTransactionId==id){
                    BeanUtils.copyProperties(financialTransaction, financialTransactionVo);
                }
            });
            //返回对象
            return financialTransactionVo;
        }
        //redis中没有数据，根据交易id查询信息
        FinancialTransaction one = this.lambdaQuery().eq(FinancialTransaction::getId, id)
                .eq(FinancialTransaction::getUserId, SecurityUtils.getUserId()).one();
        //复制
        FinancialTransactionVo vo = new FinancialTransactionVo();
        BeanUtils.copyProperties(one, vo);
        return vo;
    }
    /**
     * 查询交易记录列表
     *
     * @param financialTransaction 交易记录
     * @return 交易记录
     */
    @Autowired
    private StringRedisTemplate redisTemplate;
    @Override
    public List<FinancialTransactionVo> selectFinancialTransactionList(FinancialTransactionListDto dto) {
        String userIdStr = SecurityUtils.getUserId().toString();//当前用户id
        Long userId = SecurityUtils.getUserId();
        //先查询redis
        String cacheKey = CacheConstants.FINANCIAL_TRANSACTION_LIST_KEY + userIdStr;
        List<String> financialredisList = redisTemplate.opsForList().range(cacheKey, 0, -1);
        //查询到数据
        if (financialredisList.size() > 0) {
            ArrayList<FinancialTransactionVo> financialTransactionvo = new ArrayList<>();
            //遍历到的数据转成json对象
            financialredisList.forEach(x -> {
                FinancialTransactionVo financialTransactionVo = new FinancialTransactionVo();
                FinancialTransaction financialTransaction1 = JSON.parseObject(x, FinancialTransaction.class);
                BeanUtils.copyProperties(financialTransaction1,financialTransactionVo);
                financialTransactionVo.setType(financialTransaction1.getType());
                financialTransactionVo.setAmount(financialTransaction1.getAmount());
                financialTransactionvo.add(financialTransactionVo);
            });
            if (CollectionUtils.isEmpty(financialTransactionvo) ) {
                return financialTransactionvo;
            }
            List<FinancialTransactionVo> financialTransactionListVO = financialTransactionvo.stream()
                    .filter(txn -> {
                        // 类型匹配
                        boolean typeMatch = dto.getType() == null
                                || Objects.equals(txn.getType(), dto.getType());
                        // 分类匹配
                        boolean categoryMatch = dto.getCategory() == null
                                || Objects.equals(txn.getCategory(), dto.getCategory());
                        // 交易描述匹配
//                        boolean descMatch = financialTransaction.getDescription() == null
//                                || txn.getDescription().contains(financialTransaction.getDescription());
                        // 交易时间匹配
                        boolean timeMatch = dto.getTransactionTime() == null
                                || Objects.equals(txn.getTransactionTime(), dto.getTransactionTime());
                        //所有条件都满足才保留
                        return typeMatch && categoryMatch && timeMatch;
                    })
                    .collect(Collectors.toList());
            //返回数据
            return financialTransactionListVO;
        }
        //redis中查询不到，查询数据库
        List<FinancialTransaction> financialTransactionListq = this.lambdaQuery()
                .eq(dto.getCategory()!=null,FinancialTransaction::getCategory, dto.getCategory())
                .eq(dto.getType()!=null,FinancialTransaction::getType, dto.getType())
//                .like(financialTransaction.getDescription()!=null,FinancialTransaction::getDescription, financialTransaction.getDescription())
                .between(dto.getTransactionTime()!=null,FinancialTransaction::getTransactionTime, dto.getTransactionTime(), dto.getTransactionTime())
                .eq(FinancialTransaction::getUserId, userId)
                .list();
        //封装结果
        List<FinancialTransactionVo> voList = new ArrayList<>();
        financialTransactionListq.forEach(financialTransaction -> {
            FinancialTransactionVo vo = new FinancialTransactionVo();
            BeanUtils.copyProperties(financialTransaction,vo );
            voList.add(vo);
        });
        //查询所有数据
        List<FinancialTransaction> financialTransactionList = this.lambdaQuery().eq(FinancialTransaction::getUserId, userId).list();
        //保存到redis中
        if (financialTransactionList != null) {
            financialTransactionList.forEach(x -> {
                //设置交易世界格式为“yyyy-mm-dd”
                x.setTransactionTime(LocalDate.parse(x.getTransactionTime().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"))));
                //把数据转化成json字符串
                String string = JSON.toJSONString(x);

                redisTemplate.opsForList().leftPush(cacheKey, string);
            });
        }
        return voList;
    }

    /**
     * 新增交易记录
     *
     * @param
     * @return 结果
     */
    @Override
    public int insertFinancialTransaction(FinancialTransactionAddDto dto) {
//        return save(financialTransaction) ? 1 : 0;
        FinancialTransaction financialTransaction = new FinancialTransaction();
        //复制
        BeanUtils.copyProperties(dto, financialTransaction);
        financialTransaction.setUserId(SecurityUtils.getUserId());//用户id
        //添加
        boolean save = this.save(financialTransaction);
        if (!save) {
            return 0;
        }

        //删除缓存中的用户信息
        String userIdStr = SecurityUtils.getUserId().toString();//当前用户id
        String cacheKey = CacheConstants.FINANCIAL_TRANSACTION_LIST_KEY + userIdStr;
        redisTemplate.delete(cacheKey);
        return 1;
    }

    /**
     * 修改交易记录
     *
     * @param
     * @return 结果
     */
    @Override
    public int updateFinancialTransaction(FinancialTransactionAddDto dto) {
        FinancialTransaction financialTransaction = new FinancialTransaction();
        //复制
        BeanUtils.copyProperties(dto, financialTransaction);
        financialTransaction.setUserId(SecurityUtils.getUserId());
        boolean b = this.updateById(financialTransaction);
        if (!b){
            return 0;
        }
        //删除缓存中的用户信息
        String userIdStr = SecurityUtils.getUserId().toString();//当前用户id
        String cacheKey = CacheConstants.FINANCIAL_TRANSACTION_LIST_KEY + userIdStr;
        redisTemplate.delete(cacheKey);
        return 1;
//        return updateById(financialTransaction) ? 1 : 0;
    }

    /**
     * 批量删除交易记录
     *
     * @param ids 需要删除的交易记录主键
     * @return 结果
     */
    @Override
    public int deleteFinancialTransactionByIds(Long[] ids) {
        boolean b = this.removeBatchByIds(Arrays.asList(ids));
        if (!b){
            return 0;
        }
        //删除缓存中的用户信息
        String userIdStr = SecurityUtils.getUserId().toString();//当前用户id
        String cacheKey = CacheConstants.FINANCIAL_TRANSACTION_LIST_KEY + userIdStr;
        redisTemplate.delete(cacheKey);
        return 1;
    }

    /**
     * 删除交易记录信息
     *
     * @param id 交易记录主键
     * @return 结果
     */
    @Override
    public int deleteFinancialTransactionById(Long id) {
        return removeById(id) ? 1 : 0;
    }
}